#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define isoctal(x) ( '0' <= (x) && (x) < '8' )
#define ishexa(x)  ( isdigit(x) || 'a' <= tolower(x) && tolower(x) <= 'f')

#include "tokens.h"

extern FILE *tape;
char 		lexeme[32];
double          lexval;

isID()
{
    int             head = getc(tape);
    if (isalpha(head)) {
	int p = 0;
	lexeme[p++] = head;
        while (isalnum(head = getc(tape))) 
	  p < 31 && (lexeme[p++] = head);
	lexeme[p] = 0;
        ungetc(head, tape);
        return ID;
    }
    ungetc(head, tape);
    return 0;
}

isNUM()
{
    int             head = getc(tape);
    if (isdigit(head)) {
      int p = 0;
        if (head == '0') {
            lexeme[0] = head;
	    lexeme[1] = 0;
            lexval = 0;
            return NUM;
        }
        lexeme[p++] = head;
        while (isdigit(head = getc(tape))) 
	  (p < 10) && (lexeme[p++] = head);
        ungetc(head, tape);
	lexeme[p] = 0;
        lexval = atof(lexeme);
        return NUM;
    }
    ungetc(head, tape);
    return 0;
}

gettoken()
{
  /** tape head */
    int             head;
  /** temporary token **/
    int             token;
  /** skip spaces **/
    while (isspace(head = getc(tape)))
      if(head=='\n')
        return '\n';
    ungetc(head, tape);
  /** try each automaton next **/
    if (token = isID(tape))
        return token;
    if (token = isNUM(tape))
        return token;
    lexeme[1] = 0;
    return lexeme[0] = getc(tape);
}

/** parser interface hereafter */

int             lookahead;

void
match(int expected)
{
    if (lookahead == expected) {
        lookahead = gettoken();
    } else {
        fprintf(stderr,
                "token mismatch: found %d but %d expected\n",
                lookahead, expected);
        exit(-1);
    }
}
